package hzau.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.benmanes.caffeine.cache.Cache;
import hzau.constants.PageConstant;
import hzau.constants.ResultConstant;
import hzau.dao.CourseDao;
import hzau.dao.TeacherDao;
import hzau.dao.TeacherToCourseDao;
import hzau.dao.UserDao;
import hzau.pojo.Course;
import hzau.pojo.Teacher;
import hzau.pojo.TeacherToCourse;
import hzau.pojo.requestParams.LoginParams;
import hzau.pojo.requestParams.TeacherRegisterParam;
import hzau.result.Result;
import hzau.service.TeacherService;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.bcel.classfile.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class TeacherServiceImpl implements TeacherService {
    @Autowired
    TeacherDao teacherDao;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    TeacherToCourseDao teacherToCourseDao;
    @Autowired
    UserDao userDao;
//    @Autowired
//    RedissonClient redissonClient;
//    RLock lock=redissonClient.getLock("lock");
    @Autowired
    Cache teacherListCache;
    @Autowired
    CourseDao courseDao;
//    @Override
//    public Result login(LoginParams loginParams) {
//
//        LambdaQueryWrapper<Teacher> lqw=new LambdaQueryWrapper<>();
//        lqw.eq(Teacher::getPhoneNumber,loginParams.getUsername());
//        lqw.eq(Teacher::getPassword,loginParams.getPassword());
//        Teacher teacher = teacherDao.selectOne(lqw);
//        if (teacher!=null){
//            String token= JwtUtils.genJwt(teacher.getId());
//            redisTemplate.opsForValue().setIfAbsent(loginParams.getUsername(),token,1, TimeUnit.HOURS);
//            return  Result.success(token);
//        }else
//            return Result.error(ResultConstant.NOT_EXIST,ResultConstant.ID_NOT_EXIST);
//    }

    @Override
    public Result login(LoginParams loginParams) {
        return null;
    }

    @Override
    public Result register(TeacherRegisterParam teacher) {
        LambdaQueryWrapper<Teacher> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Teacher::getPhoneNumber,teacher.getPhoneNumber());
        Teacher teacher1 = teacherDao.selectOne(lambdaQueryWrapper);
        if (teacher1==null){
            Teacher teacher2=new Teacher(teacher);
            System.out.println(teacher2);
//            teacher2.setId(teacher.getId());
            teacherDao.insert(teacher2);
            return Result.success(null);
        }else
            return Result.error(ResultConstant.ALREADY_REGISTER_CODE,ResultConstant.ALREADY_REGISTER);
    }

    @Override
    public Result delete(Long id) {
        Teacher teacher=teacherDao.selectById(id);
        if (teacher!=null){
            Long collegeId=teacher.getCollegeId();
            deleteFromRedis(collegeId);
            teacherDao.deleteById(id);

            return Result.success(null);
        }
        else return Result.error(ResultConstant.LOGOUT_ERR_CODE,ResultConstant.LOGOUT_ERR_MSG);
    }

    @Override
    public Result update(Long id, TeacherRegisterParam teacher) {
//        deleteFromRedis(teacher.getCollegeId());
        Teacher teacher1 = new Teacher(teacher);
        teacher1.setId(id);

        teacherDao.updateById(teacher1);
        return Result.success(null);
    }

    @Override
    public Result getOne(Long id) {

        Teacher teacher = teacherDao.selectById(id);
        if (teacher!=null){
            return Result.success(teacher);
        }else
        return Result.error(ResultConstant.NOT_EXIST,ResultConstant.NO_SUCH_TEACHER);
    }


    @Override
    public Result getAll(Long collegeId, Integer pageNum) {

        Page<Teacher> page=new Page<>(pageNum, PageConstant.PAGE_SIZE);

            LambdaQueryWrapper<Teacher> lqw=new LambdaQueryWrapper<>();
            lqw.eq(Teacher::getCollegeId,collegeId);
        Page<Teacher> teacherList = teacherDao.selectPage(page, lqw);
            if (teacherList!=null){
                return Result.success(teacherList);
            }else return Result.error(ResultConstant.NOT_EXIST,ResultConstant.NO_SUCH_COLLEGE);
        }



//      spring security用的通过查找号码找教师
    @Override
    public Teacher findByPhoneNumber(String s) {
        LambdaQueryWrapper<Teacher> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Teacher::getPhoneNumber,s);
        Teacher teacher = teacherDao.selectOne(lqw);
        return teacher;
    }

    @Override
    public void testLock() {

    }


    @Override
    public Result getCourseNames(Long id) {
        LambdaQueryWrapper<Course> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Course::getCreatePaperId,id);
        lqw.eq(Course::getExpired,0);
        List<Course> courseList = courseDao.selectList(lqw);

        //TODO 根据老师的id查他教授的课程
        return Result.success(courseList);
    }

    @Override
    public Result getTeacherNames(Long courseId) {
        LambdaQueryWrapper<TeacherToCourse> lqw=new LambdaQueryWrapper<>();
        lqw.eq(TeacherToCourse::getCourseId,courseId);
        List<TeacherToCourse> teacherToCourses = teacherToCourseDao.selectList(lqw);
        List<Long> idList=new ArrayList<>();
        for (TeacherToCourse teacherToCours : teacherToCourses) {
            idList.add(teacherToCours.getTeacherId());
        }
        if(idList.size()!=0){
        List<Teacher> teacherList = teacherDao.selectBatchIds(idList);return Result.success(teacherList);}
        else return Result.success(null);

    }

    @Override
    public Result getTeachersWithoutCourse(Long courseId, Long collegeId) {
        LambdaQueryWrapper<TeacherToCourse> courselqw=new LambdaQueryWrapper<>();
        courselqw.eq(TeacherToCourse::getCourseId,courseId);
        List<TeacherToCourse> teacherToCourses = teacherToCourseDao.selectList(courselqw);
        LambdaQueryWrapper<Teacher> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Teacher::getCollegeId,collegeId);
        for(TeacherToCourse item:teacherToCourses){
            lqw.ne(Teacher::getId,item.getTeacherId());
        }
        List<Teacher> teacherList = teacherDao.selectList(lqw);
        return Result.success(teacherList);

    }

    @Override
    public Result addTeacherWithoutCourse(Long courseId, Long teacherId) {
        TeacherToCourse teacherToCourse=new TeacherToCourse();
        teacherToCourse.setTeacherId(teacherId);
        teacherToCourse.setCourseId(courseId);
        teacherToCourse.setExpired((byte) 0);
        teacherToCourseDao.insert(teacherToCourse);
        return Result.success(null);
    }

    @Override
    public Result deleteTeacherWithCourse(Long courseId, Long teacherId) {
       LambdaQueryWrapper<TeacherToCourse> lqw=new LambdaQueryWrapper<>();
       lqw.eq(TeacherToCourse::getCourseId,courseId);
       lqw.eq(TeacherToCourse::getTeacherId,teacherId);
       teacherToCourseDao.delete(lqw);
       return Result.success(null);
    }

    @Override
    public Result getTeachersTeachCourse(Long courseId, Long collegeId) {
        Course course = courseDao.selectById(courseId);
        LambdaQueryWrapper<TeacherToCourse> courselqw=new LambdaQueryWrapper<>();
        courselqw.eq(TeacherToCourse::getCourseId,courseId);
        List<TeacherToCourse> teacherToCourses = teacherToCourseDao.selectList(courselqw);
        ArrayList<Long> idList=new ArrayList<>();
        for (TeacherToCourse teacherToCours : teacherToCourses) {

            idList.add(teacherToCours.getTeacherId());
        }
        return Result.success(teacherDao.selectBatchIds(idList));
    }

    @Override
    public Result getCreateTeacher(Long courseId) {
        Course course = courseDao.selectById(courseId);
        Teacher teacher = teacherDao.selectById(course.getCreatePaperId());
        return Result.success(teacher);
    }

    @Override
    public Result getTeachersCourse(Long courseId, Long collegeId) {
        Course course = courseDao.selectById(courseId);
        LambdaQueryWrapper<TeacherToCourse> lqw =new LambdaQueryWrapper<>();
        lqw.eq(TeacherToCourse::getCourseId,courseId);
        lqw.ne(TeacherToCourse::getTeacherId,course.getCreatePaperId());
        List<TeacherToCourse> teacherToCourses = teacherToCourseDao.selectList(lqw);
        ArrayList<Long> idList=new ArrayList<>();
        for (TeacherToCourse teacherToCours : teacherToCourses) {
            idList.add(teacherToCours.getTeacherId());
        }
        List<Teacher> teacherList = teacherDao.selectBatchIds(idList);
        return Result.success(teacherList);

    }

    @Override
    public Result getReviewTeacher(Long courseId) {
        Course course = courseDao.selectById(courseId);
        Teacher teacher = teacherDao.selectById(course.getReviewPaperId());
        return Result.success(teacher);
    }

    @Override
    public Result getAllTeacher(Long collegeId) {
        LambdaQueryWrapper<Teacher> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Teacher::getCollegeId,collegeId);
        List<Teacher> teacherList = teacherDao.selectList(lqw);
        return Result.success(teacherList);
    }


    /*更新Redis中该学院教师的信息*/
    @Override
    public void updateRedis(Long collegeId) {
        String key="college_"+collegeId.toString();
        LambdaQueryWrapper<Teacher> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Teacher::getCollegeId,collegeId);
        List<Teacher> teacherList = teacherDao.selectList(lqw);
        redisTemplate.opsForValue().set(key,teacherList);
    }
    /*删除Redis中该学院教师的信息*/
    @Override
    public void deleteFromRedis(Long collegeId) {
        String key="college_"+collegeId.toString();
        redisTemplate.delete(key);
    }
//    @Override
//    public void testLock()
//    { RLock lock=redissonClient.getLock("lock");
//        boolean isLock=lock.tryLock();
//        if (!isLock){
//            log.error("获取锁失败");
//        }else try {
//            log.info("获取锁成功");
//        }finally {
//            log.info("释放锁");
//            lock.unlock();
//        }
//    }
}
